package edu.hfuu.voicedemo;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * @author scott wang
 * @date 2021/9/25
 */
public class AudioAddHeader {

    public void test(String soundKey) throws IOException {
        String originFile = "C:/audio/" + soundKey + ".wav";
        String targetFile = "C:/audio/" + soundKey + "_header.wav";

        FileInputStream fis = new FileInputStream(originFile);
        FileOutputStream fos = new FileOutputStream(targetFile);
        long size = fis.getChannel().size();
        int totalDataLen = new Long(size).intValue();
        int totalLen = new Long(size).intValue()+44;
        ByteBuffer buffer = ByteBuffer.allocate(new Long(size).intValue()+44);
        byte[] header = getHeader(totalDataLen, totalLen, 16000, 1, 16000 * 2);
        buffer.put(header);

        byte[] buf = new byte[1024];
        while(true) {
            int read = fis.read(buf);
            if (read>0) {
                byte[] bytes = Arrays.copyOfRange(buf, 0, read);
                buffer.put(bytes);
            }else{
                break;
            }
        }

        buffer.flip();
        byte[] data = new byte[totalLen];
        buffer.get(data);
        fos.write(data);
    }

    private byte[] getHeader(long totalAudioLen,
                                     long totalDataLen, long longSampleRate, int channels, long byteRate) {
        byte[] header = new byte[44];
        header[0] = 'R'; // RIFF/WAVE header
        header[1] = 'I';
        header[2] = 'F';
        header[3] = 'F';
        header[4] = (byte) (totalDataLen & 0xff);
        header[5] = (byte) ((totalDataLen >> 8) & 0xff);
        header[6] = (byte) ((totalDataLen >> 16) & 0xff);
        header[7] = (byte) ((totalDataLen >> 24) & 0xff);
        header[8] = 'W';
        header[9] = 'A';
        header[10] = 'V';
        header[11] = 'E';
        header[12] = 'f'; // 'fmt ' chunk
        header[13] = 'm';
        header[14] = 't';
        header[15] = ' ';
        header[16] = 16; // 4 bytes: size of 'fmt ' chunk
        header[17] = 0;
        header[18] = 0;
        header[19] = 0;
        header[20] = 1; // format = 1
        header[21] = 0;
        header[22] = (byte) channels;
        header[23] = 0;
        header[24] = (byte) (longSampleRate & 0xff);
        header[25] = (byte) ((longSampleRate >> 8) & 0xff);
        header[26] = (byte) ((longSampleRate >> 16) & 0xff);
        header[27] = (byte) ((longSampleRate >> 24) & 0xff);
        header[28] = (byte) (byteRate & 0xff);
        header[29] = (byte) ((byteRate >> 8) & 0xff);
        header[30] = (byte) ((byteRate >> 16) & 0xff);
        header[31] = (byte) ((byteRate >> 24) & 0xff);
        header[32] = (byte) (1 * 16 / 8); // block align
        header[33] = 0;
        header[34] = 16; // bits per sample
        header[35] = 0;
        header[36] = 'd';
        header[37] = 'a';
        header[38] = 't';
        header[39] = 'a';
        header[40] = (byte) (totalAudioLen & 0xff);
        header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
        header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
        header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
        return header;
    }

}
